home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Developer Essentials / DTS Sample Code / System 7.0 Samples / Kibitz / KibitzWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-21  |  13.2 KB  |  543 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:     Kibitz
  5. ** File:        kibitzwindow.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. */
  11.  
  12.  
  13.  
  14. /*****************************************************************************/
  15.  
  16.  
  17.  
  18. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  19. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  20. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  21.  
  22. #ifndef __ERRORS__
  23. #include <Errors.h>
  24. #endif
  25.  
  26. #ifndef __FONTS__
  27. #include <Fonts.h>
  28. #endif
  29.  
  30. #ifndef __RESOURCES__
  31. #include <Resources.h>
  32. #endif
  33.  
  34. #ifndef __TEXTEDITCONTROL__
  35. #include <TextEditControl.h>
  36. #endif
  37.  
  38. #ifndef __TOOLUTILS__
  39. #include <ToolUtils.h>
  40. #endif
  41.  
  42. #ifndef __UTILITIES__
  43. #include <Utilities.h>
  44. #endif
  45.  
  46.  
  47.  
  48. /*****************************************************************************/
  49.  
  50.  
  51.  
  52. extern short    gPrintPage;        /* Non-zero means we are printing. */
  53.  
  54. static void        ImageBoardLines(short hOffset, short vOffset);
  55.  
  56.  
  57.  
  58. /*****************************************************************************/
  59. /*****************************************************************************/
  60.  
  61.  
  62.  
  63. #pragma segment Window
  64. Boolean    Algebraic(FileRecHndl frHndl, short printMoveNum, short gameIndex, StringPtr pstr)
  65. {
  66.     short            from, to, piece, extend, rowMatch, colMatch;
  67.     short            i, r, c, rr, cc, rrr, ccc, fff, ttt, ppp;
  68.     short            color, kingLoc;
  69.     GameListHndl    gameMoves;
  70.     MoveListHndl    legalMoves;
  71.  
  72.     gameMoves = (*frHndl)->doc.gameMoves;
  73.     from = (**gameMoves)[printMoveNum].moveFrom;
  74.     to   = (**gameMoves)[printMoveNum].moveTo;
  75.  
  76.     if (!from) {
  77.         GetIndString(pstr, rGameStat, to);
  78.         while (pstr[1] == ' ') BlockMove(pstr + 2, pstr + 1, --pstr[0]);
  79.         return(false);
  80.     }
  81.  
  82.     r  = from / 10;
  83.     c  = from - 10 * r - 1;
  84.     r -= 2;
  85.  
  86.     rr  = to / 10;
  87.     cc  = to - 10 * rr - 1;
  88.     rr -= 2;
  89.  
  90.     piece = (*frHndl)->doc.theBoard[from];
  91.     if (piece < 0) piece = -piece;
  92.  
  93.     pstr[0] = 0;
  94.     if (piece == PAWN) {
  95.         if (c != cc) {
  96.             pstr[++pstr[0]] = "abcdefgh"[c];
  97.             pstr[++pstr[0]] = 'x';
  98.         }
  99.     }
  100.     if (piece == KING) {
  101.         i = c - cc;
  102.         if (i == 2) {
  103.             pstrcpy(pstr, "\pO-O-O");
  104.             piece = EMPTY;
  105.         }
  106.         if (i == -2) {
  107.             pstrcpy(pstr, "\pO-O");
  108.             piece = EMPTY;
  109.         }
  110.     }
  111.  
  112.     if (piece > PAWN) {
  113.         rowMatch = colMatch = extend = false;
  114.         GenerateLegalMoves(frHndl);
  115.         legalMoves = (*frHndl)->doc.legalMoves;
  116.         for (i = 0; i < (*frHndl)->doc.numLegalMoves; ++i) {
  117.             fff = (**legalMoves)[i].moveFrom;
  118.             ttt = (**legalMoves)[i].moveTo;
  119.             if ((ttt == to) && (fff != from)) {
  120.                 ppp = (*frHndl)->doc.theBoard[fff];
  121.                 if (ppp < 0) ppp = -ppp;
  122.                 if (ppp != piece) continue;
  123.                 rrr  = fff / 10;
  124.                 ccc  = fff - 10 * rrr - 1;
  125.                 rrr -= 2;
  126.                 extend = true;
  127.                 if (r == rrr) rowMatch = true;
  128.                 if (c == ccc) colMatch = true;
  129.             }
  130.         }
  131.         if ((extend) && (!colMatch)) rowMatch |= extend;
  132.         pstr[++pstr[0]] = "  NBRQK"[piece];
  133.         if (rowMatch)
  134.             pstr[++pstr[0]] = "abcdefgh"[c];
  135.         if (colMatch)
  136.             pstr[++pstr[0]] = "87654321"[r];
  137.         i = (*frHndl)->doc.theBoard[to];
  138.         if ((i) && (i != OBNDS)) pstr[++pstr[0]] = 'x';
  139.  
  140.     }
  141.     if (piece) {
  142.         pstr[++pstr[0]] = "abcdefgh"[cc];
  143.         pstr[++pstr[0]] = "87654321"[rr];
  144.     }
  145.     if (piece == PAWN) {
  146.         if (to = (**gameMoves)[printMoveNum].promoteTo) {
  147.             if (to < 0) to = -to;
  148.             pstr[++pstr[0]] = '=';
  149.             pstr[++pstr[0]] = "  NBRQ"[to];
  150.         }
  151.     }
  152.  
  153.     if (printMoveNum < (*frHndl)->doc.numGameMoves) {
  154.         RepositionBoard(frHndl, printMoveNum + 1, false);
  155.         kingLoc = (*frHndl)->doc.king[color = WhosMove(frHndl)].kingLoc;
  156.         if (SquareAttacked(frHndl, kingLoc, color)) pstr[++pstr[0]] = '+';
  157.         RepositionBoard(frHndl, printMoveNum, false);
  158.     }
  159.  
  160.     return(printMoveNum == gameIndex - 1);
  161. }
  162.  
  163.  
  164.  
  165. /*****************************************************************************/
  166.  
  167.  
  168.  
  169. /* This function adds the application's controls to a window. */
  170.  
  171. #pragma segment Window
  172. OSErr    AppNewWindowControls(FileRecHndl frHndl, WindowPtr window)
  173. {
  174.     OSErr            err;
  175.     TEHandle        mssgIn, mssgOut;
  176.     ControlHandle    sendMssg, beepOnMove, beepOnMssg;
  177.     Rect            destRect, viewRect, brdrRect;
  178.     ControlHandle    gameSlider, whiteStarts, blackStarts, resign, draw;
  179.     ControlHandle    record, sendSnd;
  180.     Handle            textHndl;
  181.  
  182.     SetRect(&brdrRect,
  183.             kBoardWidth + 22,
  184.             35,
  185.             rWindowWidth - 20,
  186.             kBoardHalfHeight + kBoardVOffset - 1
  187.     );
  188.     destRect = brdrRect;
  189.     InsetRect(&destRect, 4, 4);
  190.     viewRect = destRect;
  191.     destRect.right -= 2;
  192.         /* This fixes a TextEdit problem where the view has to be a little
  193.         ** outside the dest on the right, or else characters are clipped.
  194.         */
  195.  
  196.     CTENew(rViewCtl,                /* viewCtl of resID for TextEdit control. */
  197.            window,                    /* Window to hold TERecord.                  */
  198.            &mssgIn,                    /* Return handle for TERecord.               */
  199.            &destRect,                /* destRect for TERecord                  */
  200.            &viewRect,                /* viewRect for TERecord                  */
  201.            &brdrRect,                /* Used to frame a border.                  */
  202.            32000,                    /* Maximum TextEdit document length.      */
  203.            cteReadOnly+cteVScroll    /* TERecord is regular read-only.          */
  204.     );
  205.  
  206.     OffsetRect(&destRect, 0, kBoardHalfHeight - 38);
  207.     OffsetRect(&viewRect, 0, kBoardHalfHeight - 38);
  208.     OffsetRect(&brdrRect, 0, kBoardHalfHeight - 38);
  209.     CTENew(rViewCtl, window, &mssgOut, &destRect, &viewRect, &brdrRect, 32000, cteVScroll);
  210.  
  211.     if (mssgOut) {
  212.         textHndl = (Handle)(*frHndl)->doc.legalMoves;
  213.         (*frHndl)->doc.legalMoves = (MoveListHndl)CTESwapText(mssgOut, textHndl, false);
  214.             /* AppOpenDocument may have placed some text for the out-box TextEdit
  215.             ** control temporarily in the legalMoves handle.  Move this text into
  216.             ** the out-box TextEdit control. */
  217.     }
  218.  
  219.     if (sendMssg   = GetNewControl(rSendMessage, window)) HiliteControl(sendMssg, 255);
  220.     if (beepOnMove = GetNewControl(rMoveNotify, window))  HiliteControl(beepOnMove, 255);
  221.     if (beepOnMssg = GetNewControl(rMssgNotify, window))  HiliteControl(beepOnMssg, 255);
  222.  
  223.     if (whiteStarts = GetNewControl(rWhiteStarts, window)) {
  224.         OffsetControl(whiteStarts, -4096, 0);
  225.         SetCtlValue(whiteStarts, (*frHndl)->doc.startColor ^ 1);
  226.         ShowControl(whiteStarts);
  227.     }
  228.     if (blackStarts = GetNewControl(rBlackStarts, window)) {
  229.         OffsetControl(blackStarts, -4096, 0);
  230.         SetCtlValue(blackStarts, (*frHndl)->doc.startColor);
  231.         ShowControl(blackStarts);
  232.     }
  233.  
  234.     resign      = GetNewControl(rResign, window);
  235.     draw        = GetNewControl(rDraw, window);
  236.     if (record  = GetNewControl(rRecordSound, window)) HiliteControl(record, 255);
  237.     if (sendSnd = GetNewControl(rSendSound, window))   HiliteControl(sendSnd, 255);
  238.  
  239.     gameSlider = BoardSliderNew(window);
  240.  
  241.     (*frHndl)->doc.message[kMessageIn]  = mssgIn;
  242.     (*frHndl)->doc.message[kMessageOut] = mssgOut;
  243.     (*frHndl)->doc.sendMessage = sendMssg;
  244.     (*frHndl)->doc.beepOnMove  = beepOnMove;
  245.     (*frHndl)->doc.beepOnMssg  = beepOnMssg;
  246.     (*frHndl)->doc.gameSlider  = gameSlider;
  247.     (*frHndl)->doc.wbStart[0]  = whiteStarts;
  248.     (*frHndl)->doc.wbStart[1]  = blackStarts;
  249.     (*frHndl)->doc.resign      = resign;
  250.     (*frHndl)->doc.draw        = draw;
  251.     (*frHndl)->doc.record      = record;
  252.     (*frHndl)->doc.sendSnd     = sendSnd;
  253.  
  254.     if (
  255.         (mssgIn) &&
  256.         (mssgOut) &&
  257.         (sendMssg) &&
  258.         (beepOnMove) &&
  259.         (beepOnMssg) &&
  260.         (resign) &&
  261.         (draw) &&
  262.         (record) &&
  263.         (sendSnd)
  264.     ) {
  265.         AdjustGameSlider(frHndl);
  266.         err = noErr;
  267.     }
  268.     else
  269.         err = memFullErr;
  270.  
  271.     return(err);
  272. }
  273.  
  274.  
  275.  
  276. /*****************************************************************************/
  277.  
  278.  
  279.  
  280. #pragma segment Window
  281. void    DrawTime(FileRecHndl frHndl)
  282. {
  283.     WindowPtr        oldPort;
  284.     Rect            clockRect;
  285.     short            clock, i, time[3];
  286.     unsigned long    timeLeft, displayTime;
  287.     char            pstr[5], timestr[10];
  288.  
  289.     if ((*frHndl)->doc.arrangeBoard) return;
  290.  
  291.     oldPort = SetFilePort(frHndl);
  292.  
  293.     TextMode(srcCopy);
  294.     TextFont(systemFont);
  295.  
  296.     for (clock = 0; clock < 2; ++clock) {
  297.  
  298.         clockRect = BoardRect();
  299.  
  300.         if (clock == (*frHndl)->doc.invertBoard)
  301.             clockRect.top += 14;
  302.  
  303.         clockRect.left   = clockRect.right + 4;
  304.         clockRect.right  = clockRect.left + 70;
  305.         clockRect.bottom = clockRect.top + 14;
  306.  
  307.         timeLeft = (*frHndl)->doc.timeLeft[clock];
  308.         if (timeLeft == -1) {
  309.             EraseRect(&clockRect);
  310.             continue;
  311.         }
  312.  
  313.         if ((displayTime = (*frHndl)->doc.displayTime[clock]) > timeLeft)
  314.              displayTime = (*frHndl)->doc.displayTime[clock]  = timeLeft;
  315.  
  316.         MoveTo(clockRect.left + 6, clockRect.top + 14);
  317.  
  318.         for (i = 3; i;) {
  319.             displayTime /= 60;
  320.             time[--i] = displayTime % 60;
  321.         }
  322.         timestr[0] = 0;
  323.         for (i = 0; i < 3; ++i) {
  324.             i2pstr(pstr, time[i]);
  325.             if (pstr[0] == 1) pstrcat(timestr, "\p0");
  326.             pstrcat(timestr, pstr);
  327.             pstrcat(timestr, "\1:\1:\1 " + (i << 1));    /* Append colon or space. */
  328.         }
  329.         DrawString(timestr);
  330.     }
  331.  
  332.     TextMode(srcOr);
  333.     SetPort(oldPort);
  334. }
  335.  
  336.  
  337.  
  338. /*****************************************************************************/
  339.  
  340.  
  341.  
  342. #pragma segment Window
  343. void    ImageBoardLines(short hOffset, short vOffset)
  344. {
  345.     short    i;
  346.  
  347.     PenNormal();
  348.     PenSize(2, 2);
  349.  
  350.     for (i = 0; i <= 8; ++i) {
  351.         MoveTo(hOffset, vOffset + kBoardSqSize * i);
  352.         Line(kBoardSqSize * 8, 0);
  353.         MoveTo(hOffset + kBoardSqSize * i, vOffset);
  354.         Line(0, kBoardSqSize * 8);
  355.     }
  356.  
  357.     PenNormal();
  358. }
  359.  
  360.  
  361.  
  362. /*****************************************************************************/
  363.  
  364.  
  365.  
  366. /* Image the document into the current port. */
  367.  
  368. #pragma segment Window
  369. void    ImageDocument(FileRecHndl frHndl, Boolean justBoard)
  370. {
  371. #pragma unused (frHndl)
  372.  
  373.     short            r, c, rr, cc, piece, pieceIconID, fnum;
  374.     short            gameIndex, lastFrom, lastTo, square, hOffset, vOffset;
  375.     Boolean            invertBoard;
  376.     Handle            pieceIcon;
  377.     Rect            sqRect, theInk;
  378.     GameListHndl    gameMoves;
  379.     WindowPtr        thePort;
  380.  
  381.     hOffset = kBoardHOffset;
  382.     vOffset = kBoardVOffset;
  383.     if (gPrintPage) {
  384.         GetPort(&thePort);
  385.         theInk = thePort->portRect;
  386.         GetFNum("\pTimes", &fnum);
  387.         TextFont(fnum);
  388.         TextSize(12);
  389.         TextFace(normal);
  390.         hOffset = theInk.right - 10 - kBoardWidth;
  391.         vOffset = 10;
  392.     }
  393.     else ImageBoardLines(hOffset, vOffset);
  394.  
  395.     invertBoard = (*frHndl)->doc.invertBoard;
  396.     lastFrom = lastTo = 0;
  397.     gameIndex = (*frHndl)->doc.gameIndex;
  398.     gameMoves = (*frHndl)->doc.gameMoves;
  399.     if (gameIndex) {
  400.         lastFrom = (**gameMoves)[--gameIndex].moveFrom;
  401.         lastTo   = (**gameMoves)[gameIndex++].moveTo;
  402.     }
  403.  
  404.     if (gPrintPage < 2) {        /* If not printing, or printing first page... */
  405.         for (r = 0; r < 8; ++r) {
  406.             for (c = 0; c < 8; ++c) {
  407.                 piece = (*frHndl)->doc.theBoard[square = START_IBNDS + 10 * r + c];
  408.                 pieceIconID = piece + 257 + KING;
  409.  
  410.                 rr = r;
  411.                 cc = c;
  412.                 if (invertBoard) {
  413.                     rr = 7 - r;
  414.                     cc = 7 - c;
  415.                 }
  416.  
  417.                 if ((rr + cc) & 0x01) pieceIconID += 13;
  418.                 pieceIcon = GetResource('ICN#', pieceIconID);
  419.  
  420.                 sqRect.top    = vOffset + kBoardSqSize * rr + 3;
  421.                 sqRect.left   = hOffset + kBoardSqSize * cc + 3;
  422.                 sqRect.bottom = sqRect.top  + 32;
  423.                 sqRect.right  = sqRect.left + 32;
  424.                 PlotIcon(&sqRect, pieceIcon);
  425.  
  426.                 if ((square == lastFrom) || (square == lastTo))
  427.                     FrameRect(&sqRect);
  428.             }
  429.         }
  430.     }
  431.  
  432.     if (gPrintPage) {                /* If printing... */
  433.         if (gPrintPage == 1)        /* If printing page 1... */
  434.             ImageBoardLines(hOffset, vOffset);
  435.         ImageMoveList(frHndl, theInk, hOffset);
  436.         return;
  437.     }
  438.  
  439.     if (!justBoard) {
  440.         GetPort(&thePort);
  441.         SetOrigin((*frHndl)->doc.arrangeBoard * 4096, 0);
  442.         UpdateGameStatus(frHndl);
  443.         DoDrawControls(thePort, false);
  444.         OutlineControl((*frHndl)->doc.sendMessage);
  445.         DrawTime(frHndl);
  446.         DrawPalette(frHndl);
  447.         SetOrigin(0, 0);
  448.     }
  449. }
  450.  
  451.  
  452.  
  453. /*****************************************************************************/
  454.  
  455.  
  456.  
  457. #pragma segment Window
  458. void    ImageMoveList(FileRecHndl frHndl, Rect theInk, short hOffset)
  459. {
  460.     short    gameIndex, numGameMoves, printMoveNum, colsPerPage, colHeight;
  461.     short    pageNum, colNum, colVOffset, numMovePairs, colEndMove, hloc, vloc;
  462.     Str255    pstr;
  463.  
  464.     gameIndex    = (*frHndl)->doc.gameIndex;
  465.     numGameMoves = (*frHndl)->doc.numGameMoves;
  466.     printMoveNum = (*frHndl)->doc.startColor;
  467.     colsPerPage  = (theInk.right  - theInk.left) / 180;
  468.     colHeight    = (theInk.bottom - theInk.top) - 2 * kBoardHOffset;
  469.  
  470.     for (pageNum = 1; pageNum <= gPrintPage; ++pageNum) {
  471.  
  472.         for (colNum = 1; colNum <= colsPerPage; ++colNum) {
  473.  
  474.             hloc = colNum * 180 - 120;
  475.  
  476.             colVOffset = 0;
  477.             if (pageNum == 1) {
  478.                 if (colNum == 1) colVOffset = (3 * 20);
  479.                 if (hloc + 130 >= hOffset)
  480.                     for (; colVOffset < (kBoardHeight + 20 + kBoardVOffset); colVOffset += 20);
  481.                         /* Start this column below the board on 20-pixel boundary. */
  482.             }
  483.  
  484.             numMovePairs = (colHeight - colVOffset) / 20;
  485.             colEndMove   = printMoveNum + 2 * numMovePairs;
  486.  
  487.             if (pageNum == gPrintPage) {
  488.  
  489.                 if ((pageNum == 1) && (colNum == 1)) {
  490.                     MoveTo(hloc, theInk.top + 20);
  491.                     pstrcpy(pstr, (*frHndl)->fileState.fss.name);
  492.                     TextFace(bold + underline);
  493.                     DrawString(pstr);
  494.                     TextFace(normal);
  495.                 }
  496.  
  497.                 for (; printMoveNum < colEndMove; ++printMoveNum) {
  498.  
  499.                     RepositionBoard(frHndl, printMoveNum, false);
  500.  
  501.                     if (printMoveNum >= numGameMoves) {
  502.                         gPrintPage = 0;
  503.                         RepositionBoard(frHndl, gameIndex, false);
  504.                         return;
  505.                     }
  506.  
  507.                     vloc = theInk.top + colVOffset + 20;
  508.  
  509.                     if (!(printMoveNum & 0x01)) {
  510.                         i2pstr(pstr, printMoveNum / 2 + 1);
  511.                         MoveTo(hloc - 16 - StringWidth(pstr), vloc);
  512.                         DrawString(pstr);
  513.                         DrawString("\p)");
  514.                         MoveTo(hloc, vloc);
  515.                     }
  516.                     else {
  517.                         MoveTo(hloc + 40, vloc);
  518.                         MoveTo(hloc + 40 + 12, vloc);
  519.                         colVOffset += 20;
  520.                     }
  521.  
  522.                     if (Algebraic(frHndl, printMoveNum, gameIndex, pstr))
  523.                         TextFace(underline);
  524.  
  525.                     DrawString(pstr);
  526.                     TextFace(normal);
  527.                 }
  528.             }
  529.  
  530.             if ((printMoveNum = colEndMove) >= numGameMoves) {
  531.                 gPrintPage = 0;
  532.                 RepositionBoard(frHndl, gameIndex, false);
  533.                 return;
  534.             }
  535.         }
  536.     }
  537.  
  538.     RepositionBoard(frHndl, gameIndex, false);
  539. }
  540.  
  541.  
  542.  
  543.